package gov.dhs.cis.moc.tools;

import gov.dhs.cis.soa.SOAData;
import gov.dhs.cis.soa.Utils;
import gov.dhs.cis.soa.data.Service;
import gov.dhs.cis.soa.data.ServiceOperation;
import gov.dhs.cis.soa.generators.EADocumentPersistor;
import gov.dhs.cis.soa.readers.ExcelReader;
import gov.dhs.cis.soa.readers.ServicesLayerReader;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class MOCDifferences extends ExcelReader {
	static final Logger loger = Logger.getLogger(MOCDifferences.class);

	final String MOC_FILE = "Master Object Catalog - 2010-06-21.bdm.xls";
	final String MOC_SERV_TAB_NAME = "Services";
	final String MOC_SERV_OP_TAB_NAME = "Services Operations";
	final int MAX_SERVS = 155;
	final int MAX_SERV_OPS = 420;
	
	public SOAData loadArchServiceDefs() {
		SOAData soaData = new SOAData();
		ServicesLayerReader servReader = new ServicesLayerReader();
		soaData = servReader.extractServices(soaData);
		soaData = servReader.extractServiceOperations(soaData);
		return soaData;
	}
	
	public ArrayList<Service> loadMocServiceDefs() {
		final String SERV_COL_NUM = "F";
		final String DESC_COL_NUM = "G";
		final String STEREO_COL_NUM = "I";
		final String WIPT_COL_NUM = "J";
		final String REL_COL_NUM = "K";
		final String MATURITY_COL_NUM = "L";

		final String OP_SERV_COL_NUM = "P";
		final String OP_OPER_COL_NUM = "Q";
		final String OP_DATA_IN_COL_NUM = "R";
		final String OP_DATA_OUT_COL_NUM = "S";
		
		HSSFWorkbook w = openFile(MOC_FILE);
		HSSFSheet s1 = w.getSheet(MOC_SERV_TAB_NAME);
		ArrayList<Service> moc_services = new ArrayList<Service>();
		int n = 0;
		for (n = 2; n < MAX_SERVS; n++) {
			HSSFRow row = s1.getRow(n);
			if(row == null)
				continue;
			String data = getCellStringValue(w, row, SERV_COL_NUM);
			if(Utils.isEmpty(data)) {
				loger.warn("Service Name is Null/Empty at row : " + n + ", ignoring this row.");
				continue;
			}
			Service s = new Service();
			s.id = Utils.getNextId();
			s.name = getCellStringValue(w, row, SERV_COL_NUM);
			s.descText = getCellStringValue(w, row, DESC_COL_NUM);
			s.stereotype = getCellStringValue(w, row, STEREO_COL_NUM);
			if(Utils.isEmpty(s.stereotype))
				s.stereotype = Service.STEREO_TYPE;
			s.wipt = getCellStringValue(w, row, WIPT_COL_NUM);
			if(Utils.isEmpty(s.wipt))
				s.wipt = "-1";
			s.release = Utils.convert2Release(getCellStringValue(w, row, REL_COL_NUM));
			s.maturity = ""+Utils.convert1stchar2Int(getCellStringValue(w, row, MATURITY_COL_NUM));
			moc_services.add(s);
		}
		s1 = w.getSheet(MOC_SERV_OP_TAB_NAME);
		for (n = 2; n < MAX_SERV_OPS; n++) {
			HSSFRow row = s1.getRow(n);
			if(row == null)
				continue;

			String servName = getCellStringValue(w, row, OP_SERV_COL_NUM);
			if(Utils.isEmpty(servName)) {
				loger.warn("Service Name is Null/Empty at row : " + n + ", ignoring this row.");
				continue;
			}
			Service s = Utils.findServiceByName(servName, moc_services);
			if(s == null) {
				loger.error("Couldnt locate Service <" + servName + "> at row : " + n + ", ignoring this row.");
				continue;
			}
			String servOpName = getCellStringValue(w, row, OP_OPER_COL_NUM);
			if(Utils.isEmpty(servOpName)) {
				loger.warn(servName + ": Operation Name is Null/Empty at row : " + n + ", ignoring this row.");
				continue;
			}
			ServiceOperation sOp = new ServiceOperation();
			sOp.name = servOpName;
			sOp.id = Utils.getNextId();
			sOp.dataIn = getCellStringValue(w, row, OP_DATA_IN_COL_NUM);
			sOp.dataOut = getCellStringValue(w, row, OP_DATA_OUT_COL_NUM);
			s.add(sOp);
		}
		
		closeAll(w);
		return moc_services;
	}
	
	public void compareServiceDef(List<Service> archServiceDef, List<Service> mocServDefs) {
		for(Service serv : archServiceDef) {
			Service foundServ = Utils.findServiceByName(serv.name, mocServDefs);
			if (foundServ == null) {
				loger.error("SERV | " + serv.name + " | MOC");
			} else {
				ArrayList<ServiceOperation> combinedOps = new ArrayList<ServiceOperation>();
				if(serv.opList != null)
					combinedOps.addAll(serv.opList);
				for(ServiceOperation servOp : combinedOps) {
					ServiceOperation foundOp = foundServ.findOperation(servOp.name);
					if(foundOp == null)
						loger.error("SERVOP | " + foundServ.name + "." + servOp.name + " | MOC");
				}
			}
		}
		for(Service serv : mocServDefs) {
			Service foundServ = Utils.findServiceByName(serv.name, archServiceDef);
			if (foundServ == null) {
				loger.error("SERV | " + serv.name + " | ARCH");
			} else {
				ArrayList<ServiceOperation> combinedOps = new ArrayList<ServiceOperation>();
				if(serv.opList != null)
					combinedOps.addAll(serv.opList);
				for(ServiceOperation servOp : combinedOps) {
					ServiceOperation foundOp = foundServ.findOperation(servOp.name);
					if(foundOp == null)
						loger.error("SERVOP | " + foundServ.name + "." + servOp.name + " | ARCH");
				}
			}
		}
	}
	
	public static void main(String[] args) {
		EADocumentPersistor persistor = new EADocumentPersistor();
		persistor.initLog4J();

		MOCDifferences mocDiff = new MOCDifferences();
		SOAData soaData = mocDiff.loadArchServiceDefs();
		List<Service>mocServDefs = mocDiff.loadMocServiceDefs();
		mocDiff.compareServiceDef(soaData.servList, mocServDefs);
	}
}
